//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32

//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
#define HUMAN_MAX_OXYLOSS 3 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it.
#define HUMAN_CRIT_MAX_OXYLOSS ( (last_tick_duration) /3) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 100HP to get through, so (1/3)*last_tick_duration per second. Breaths however only happen every 4 ticks.

/mob/living/carbon/human
	var/oxygen_alert = 0
	var/breath = 1
	var/prev_gender = null // Debug for plural genders


/mob/living/carbon/human/Life()
	set invisibility = 0
	set background = 1

	if (monkeyizing)	return
	if(!loc)			return	// Fixing a null error that occurs when the mob isn't found in the world -- TLE

	..()

	//Apparently, the person who wrote this code designed it so that
	//blinded get reset each cycle and then get activated later in the
	//code. Very ugly. I dont care. Moving this stuff here so its easy
	//to find it.
	blinded = null
	//No need to update all of these procs if the guy is dead.
	if(stat != DEAD)
		if((last_tick_duration) || failed_last_breath) 	//First, resolve location and get a breath
			breathe() 				//Only try to take a breath every last tick duration, unless suffocating

		//Updates the number of stored chemicals for powers
		handle_changeling()

		//Mutations and radiation
		handle_mutations_and_radiation()

		//Chemicals in the body
		handle_chemicals_in_body()

		//Disabilities
		handle_disabilities()

		//Random events (vomiting etc)
		handle_random_events()

		//Breathing.
		handle_breath()

	//stuff in the stomach
	handle_stomach()

	//Status updates, death etc.
	handle_regular_status_updates()		//TODO: optimise ~Carn
	update_canmove()

	//Update our name based on whether our face is obscured/disfigured
	name = get_visible_name()

	handle_regular_hud_updates()

	// Grabbing
	for(var/obj/item/weapon/grab/G in src)
		G.process()

/mob/living/carbon/human

	proc/handle_disabilities()
		if (disabilities & EPILEPSY)
			if ((prob(1) && paralysis < 1))
				src << "\red You have a seizure!"
				for(var/mob/O in viewers(src, null))
					if(O == src)
						continue
					O.show_message(text("\red <B>[src] starts having a seizure!"), 1)
				Paralyse(10)
				make_jittery(1000)
		if (disabilities & COUGHING)
			if ((prob(5) && paralysis <= 1))
				drop_item()
				spawn( 0 )
					emote("cough")
					return
		if (disabilities & TOURETTES)
			if ((prob(10) && paralysis <= 1))
				Stun(10)
				spawn( 0 )
					switch(rand(1, 3))
						if(1)
							emote("twitch")
						if(2 to 3)
							say("[pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]")
					var/old_x = pixel_x
					var/old_y = pixel_y
					pixel_x += rand(-2,2)
					pixel_y += rand(-1,1)
					sleep(2)
					pixel_x = old_x
					pixel_y = old_y
					return
		if (disabilities & NERVOUS)
			if (prob(10))
				stuttering = max(10, stuttering)
		if (getBrainLoss() >= 50 && stat != 2)
			if (prob(3))
				emote("drool")
			if (prob(5))
				emote("moan")


	proc/handle_mutations_and_radiation()
		if(getFireLoss())
			if((COLD_RESISTANCE in mutations) || (prob(1)))
				heal_organ_damage(0,1)

		if ((HULK in mutations) && health <= 25)
			mutations.Remove(HULK)
			update_mutations()		//update our mutation overlays
			src << "\red You suddenly feel very weak."
			Weaken(3)
			emote("collapse")

		if (radiation)
			if (radiation > 100)
				radiation = 100
				Weaken(10)
				src << "\red You feel weak."
				emote("collapse")

			if (radiation < 0)
				radiation = 0

			else
				switch(radiation)
					if(1 to 49)
						radiation--
						if(prob(25))
							adjustToxLoss(1)
							updatehealth()

					if(50 to 74)
						radiation -= 2
						adjustToxLoss(1)
						if(prob(5))
							radiation -= 5
							Weaken(3)
							src << "\red You feel weak."
							emote("collapse")
						if(prob(15))
							if(!(f_style == "Shaved") || !(h_style == "Bald"))
								src << "<span class='danger'>Your hair starts to fall out in clumps...<span>"
								spawn(50)
									f_style = "Shaved"
									h_style = "Bald"
									update_hair()
						updatehealth()

					if(75 to 100)
						radiation -= 3
						adjustToxLoss(3)
						if(prob(1))
							src << "\red You mutate!"
							randmutb(src)
							domutcheck(src,null)
							emote("gasp")
						updatehealth()


	proc/breathe()
		for(var/obj/effect/effect/chem_smoke/smoke in view(1, src))
			smoke.reagents.reaction(src, INGEST)
			spawn(5)
				if(smoke)
					smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
				break // If they breathe in the nasty stuff once, no need to continue checking

	proc/handle_breath()
		if(reagents.has_reagent("epinephrine"))
			return
		if(health >= config.health_threshold_crit)
			adjustOxyLoss(-HUMAN_MAX_OXYLOSS*2)
		if(health <= config.health_threshold_crit)
			adjustOxyLoss(HUMAN_MAX_OXYLOSS*2)

			return 0

	proc/handle_chemicals_in_body()
		if(reagents) reagents.metabolize(src)

		if(dna && dna.mutantrace == "plant") //couldn't think of a better place to place it, since it handles nutrition -- Urist
			var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
			if(isturf(loc)) //else, there's considered to be no light
				var/turf/T = loc
				var/area/A = T.loc
				if(A)
					if(A.lighting_use_dynamic)	light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
					else						light_amount =  5
			nutrition += light_amount
			if(nutrition > 500)
				nutrition = 500
			if(light_amount > 2) //if there's enough light, heal
				heal_overall_damage(1,1)
				adjustToxLoss(-1)
				adjustOxyLoss(-1)
		if(dna && dna.mutantrace == "shadow")
			var/light_amount = 0
			if(isturf(loc))
				var/turf/T = loc
				var/area/A = T.loc
				if(A)
					if(A.lighting_use_dynamic)	light_amount = T.lighting_lumcount
					else						light_amount =  10
			if(light_amount > 2) //if there's enough light, start dying
				take_overall_damage(1,1)
			else if (light_amount < 2) //heal in the dark
				heal_overall_damage(1,1)

		/*The fucking FAT mutation is the dumbest shit ever. It makes the code so difficult to work with
		if(FAT in mutations)
			if(overeatduration < 100)
				src << "\blue You feel fit again!"
				mutations.Remove(FAT)
				update_mutations(0)
				update_inv_w_uniform(0)
				update_inv_wear_suit()
		else
			if(overeatduration > 500)
				src << "\red You suddenly feel blubbery!"
				mutations.Add(FAT)
				update_mutations(0)
				update_inv_w_uniform(0)
				update_inv_wear_suit()*/

		// nutrition decrease
		if (nutrition > 0 && stat != 2)
			nutrition = max (0, nutrition - HUNGER_FACTOR)

		if (nutrition > 450)
			if(overeatduration < 600) //capped so people don't take forever to unfat
				overeatduration++
		else
			if(overeatduration > 1)
				overeatduration -= 2 //doubled the unfat rate

		if(dna && dna.mutantrace == "plant")
			if(nutrition < 200)
				take_overall_damage(2,0)

		if(nutrition < 300)
			if(prob(2))
				src << "Your stomach rumbles lightly."
		if(nutrition < 250)
			if(prob(3))
				src << "Your stomach rumbles. You should probably eat soon."
		if(nutrition < 200)
			if(prob(2))
				src << "Your stomach rumbles loudly. \red So hungry..."
				adjustBruteLoss(2)
		if(nutrition < 150)
			if(prob(2))
				src << "Your stomach rumbling is insane. \red You feel as though you could eat an entire HORSE right now with how hungry you are!"
				adjustBruteLoss(4)
		if(nutrition < 100)
			if(prob(5))
				src << "Your stomach rumbles horribly. \red (If you do not eat soon, you will die!)"
				adjustBruteLoss(8)

		if (drowsyness)
			drowsyness--
			eye_blurry = max(2, eye_blurry)
			if (prob(drowsyness/5))
				sleeping += 1

		confused = max(0, confused - 1)
		// decrement dizziness counter, clamped to 0
		if(resting)
			dizziness = max(0, dizziness - 15)
			jitteriness = max(0, jitteriness - 15)
		else
			dizziness = max(0, dizziness - 3)
			jitteriness = max(0, jitteriness - 3)

		updatehealth()

		return //TODO: DEFERRED

	proc/handle_regular_status_updates()
		if(stat == DEAD)	//DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
			breath = 0
			blinded = 1
			silent = 0
		else				//ALIVE. LIGHTS ARE ON
			adjustOxyLoss(-3) //Recover a little faster due to not being in critical.
			updatehealth()	//TODO
			if(health <= config.health_threshold_dead || !getbrain(src))
				death()
				blinded = 1
				silent = 0
				return 1


			//UNCONSCIOUS. NO-ONE IS HOME
			if( (getOxyLoss() > 75) || (config.health_threshold_crit >= health) )
				breath = 0
				Paralyse(3)

				/* Done by handle_breath()
				if( health <= 20 && prob(1) )
					spawn(0)
						emote("gasp")
				if(!reagents.has_reagent("epinephrine"))
					adjustOxyLoss(1)*/

			if(hallucination)
				if(hallucination >= 20)
					if(prob(3))
						fake_attack(src)
					if(!handling_hal)
						spawn handle_hallucinations() //The not boring kind!

				if(hallucination<=2)
					hallucination = 0
					halloss = 0
				else
					hallucination -= 1

			else
				for(var/atom/a in hallucinations)
					del a

				if(halloss > 100)
					src << "<span class='notice'>You're too tired to keep going...</span>"
					for(var/mob/O in oviewers(src, null))
						O.show_message("<B>[src]</B> slumps to the ground panting, too weak to continue.", 1)
					Paralyse(15)
					setHalLoss(25)

			if(paralysis)
				AdjustParalysis(-1)
				blinded = 1
				stat = UNCONSCIOUS
			else if(sleeping)
				handle_dreams()
				adjustHalLoss(-3)
				sleeping = max(sleeping-1, 0)
				blinded = 1
				stat = UNCONSCIOUS
				if( prob(10) && health && !hal_crit )
					spawn(0)
						emote("snore")
			//CONSCIOUS
			else
				stat = CONSCIOUS

			//Eyes
			if(sdisabilities & BLIND && !istype(glasses, /obj/item/clothing/glasses/sunglasses/visor))	//disabled-blind, doesn't get better on its own
				blinded = 1
			else if(eye_blind && !istype(glasses, /obj/item/clothing/glasses/sunglasses/visor))			//blindness, heals slowly over time
				eye_blind = max(eye_blind-1,0)
				blinded = 1
			else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold))	//resting your eyes with a blindfold heals blurry eyes faster
				eye_blurry = max(eye_blurry-3, 0)
				eye_blind = max(eye_blind-2,0)
				blinded = 1
			else if(eye_blurry)	//blurry eyes heal slowly
				eye_blurry = max(eye_blurry-1, 0)
			else if(REGENERATION in mutations)
				eye_blurry = max(eye_blurry-4, 0)
				eye_blind = max(eye_blind-3,0)
				blinded = 1
			else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/visor))
				eye_blurry = max(eye_blurry-1, 0)
				eye_blind = max(eye_blind-1,0)
				blinded = 0	//VISOR boosts recovery of vision and prevents lack of sight.


			//Ears
			if(sdisabilities & DEAF)	//disabled-deaf, doesn't get better on its own
				ear_deaf = max(ear_deaf, 1)
			else if(ear_deaf)			//deafness, heals slowly over time
				ear_deaf = max(ear_deaf-1, 0)
			else if(istype(ears, /obj/item/clothing/ears/earmuffs))	//resting your ears with earmuffs heals ear damage faster
				ear_damage = max(ear_damage-0.15, 0)
				ear_deaf = max(ear_deaf, 1)
			else if(ear_damage < 25)	//ear damage heals slowly under this threshold. otherwise you'll need earmuffs
				ear_damage = max(ear_damage-0.05, 0)
			else if(REGENERATION in mutations)
				ear_damage = max(ear_damage-0.45, 0)
				ear_deaf = max(ear_deaf-3, 0)

			//Other
			if(stunned)
				AdjustStunned(-1)

			if(weakened)
				weakened = max(weakened-1,0)	//before you get mad Rockdtben: I done this so update_canmove isn't called multiple times

			if(stuttering)
				stuttering = max(stuttering-1, 0)

			if(silent)
				silent = max(silent-1, 0)

			if(druggy)
				druggy = max(druggy-1, 0)

			if(REGENERATION in mutations)
				adjustToxLoss(-1)
				adjustFireLoss(-1)
				adjustBruteLoss(-1)
				adjustOxyLoss(-1)
				adjustCloneLoss(-1)
				adjustBrainLoss(-1)
				adjustHalLoss(-1)

		return 1

	proc/handle_regular_hud_updates()
		if(!client)	return 0

		for(var/image/hud in client.images)
			if(copytext(hud.icon_state,1,4) == "hud") //ugly, but icon comparison is worse, I believe
				client.images.Remove(hud)

		client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask)

		update_action_buttons()

		if( stat == DEAD )
			sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
			see_in_dark = 8
			if(!druggy)		see_invisible = SEE_INVISIBLE_LEVEL_TWO
			if(healths)		healths.icon_state = "health7"	//DEAD healthmeter
		else
			sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
			if(dna)
				switch(dna.mutantrace)
					if("shadow")
						see_in_dark = 8
					else
						see_in_dark = 2

			if(XRAY in mutations)
				sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
				see_in_dark = 8
				if(!druggy)		see_invisible = SEE_INVISIBLE_LEVEL_TWO

				see_invisible = SEE_INVISIBLE_LIVING
				seer = 0

			if(istype(wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja))
				var/obj/item/clothing/mask/gas/voice/space_ninja/O = wear_mask
				switch(O.mode)
					if(0)
						var/target_list[] = list()
						for(var/mob/living/target in oview(src))
							if( target.mind&&(target.mind.special_role||issilicon(target)) )//They need to have a mind.
								target_list += target
						if(target_list.len)//Everything else is handled by the ninja mask proc.
							O.assess_targets(target_list, src)
						if(!druggy)		see_invisible = SEE_INVISIBLE_LIVING
					if(1)
						see_in_dark = 5
						if(!druggy)		see_invisible = SEE_INVISIBLE_LIVING
					if(2)
						sight |= SEE_MOBS
						if(!druggy)		see_invisible = SEE_INVISIBLE_LEVEL_TWO
					if(3)
						sight |= SEE_TURFS
						if(!druggy)		see_invisible = SEE_INVISIBLE_LIVING

			if(glasses)
				if(istype(glasses, /obj/item/clothing/glasses/meson))
					sight |= SEE_TURFS
					if(!druggy)
						see_invisible = SEE_INVISIBLE_MINIMUM
				else if(istype(glasses, /obj/item/clothing/glasses/night))
					see_in_dark = 5
					if(!druggy)
						see_invisible = SEE_INVISIBLE_MINIMUM
				else if(istype(glasses, /obj/item/clothing/glasses/thermal))
					sight |= SEE_MOBS
					if(!druggy)
						see_invisible = SEE_INVISIBLE_MINIMUM
				else if(istype(glasses, /obj/item/clothing/glasses/material))
					sight |= SEE_OBJS
					if(!druggy)
						see_invisible = SEE_INVISIBLE_MINIMUM

	/* HUD shit goes here, as long as it doesn't modify sight flags */
	// The purpose of this is to stop xray and w/e from preventing you from using huds -- Love, Doohl

				else if(istype(glasses, /obj/item/clothing/glasses/sunglasses))
					see_in_dark = 1
					if(istype(glasses, /obj/item/clothing/glasses/sunglasses/sechud))
						var/obj/item/clothing/glasses/sunglasses/sechud/O = glasses
						if(O.hud)		O.hud.process_hud(src)
						if(!druggy)		see_invisible = SEE_INVISIBLE_LIVING

				else if(istype(glasses, /obj/item/clothing/glasses/hud))
					var/obj/item/clothing/glasses/hud/O = glasses
					O.process_hud(src)
					if(!druggy)
						see_invisible = SEE_INVISIBLE_LIVING
				else
					see_invisible = SEE_INVISIBLE_LIVING
			else
				see_invisible = SEE_INVISIBLE_LIVING

			if(healths)
				switch(hal_screwyhud)
					if(1)	healths.icon_state = "health6"
					if(2)	healths.icon_state = "health7"
					else
						switch(health - halloss)
							if(100 to INFINITY)		healths.icon_state = "health0"
							if(80 to 100)			healths.icon_state = "health1"
							if(60 to 80)			healths.icon_state = "health2"
							if(40 to 60)			healths.icon_state = "health3"
							if(20 to 40)			healths.icon_state = "health4"
							if(0 to 20)				healths.icon_state = "health5"
							else					healths.icon_state = "health6"

			if(nutrition_icon)
				switch(nutrition)
					if(450 to INFINITY)				nutrition_icon.icon_state = "nutrition0"
					if(350 to 450)					nutrition_icon.icon_state = "nutrition1"
					if(250 to 350)					nutrition_icon.icon_state = "nutrition2"
					if(150 to 250)					nutrition_icon.icon_state = "nutrition3"
					else							nutrition_icon.icon_state = "nutrition4"


			if(pullin)
				if(pulling)								pullin.icon_state = "pull"
				else									pullin.icon_state = "pull0"
//			if(rest)	//Not used with new UI
//				if(resting || lying || sleeping)		rest.icon_state = "rest1"
//				else									rest.icon_state = "rest0"

			if(blind)
				if(blinded)		blind.layer = 18
				else			blind.layer = 0

			if( disabilities & NEARSIGHTED && !istype(glasses, /obj/item/clothing/glasses/regular) )
				client.screen += global_hud.vimpaired
			if(eye_blurry)			client.screen += global_hud.blurry
			if(druggy)				client.screen += global_hud.druggy

			var/masked = 0

			if( istype(head, /obj/item/clothing/head/welding) )
				var/obj/item/clothing/head/welding/O = head
				if(!O.up && tinted_weldhelh)
					client.screen += global_hud.darkMask
					masked = 1

			if(!masked && istype(glasses, /obj/item/clothing/glasses/welding) )
				var/obj/item/clothing/glasses/welding/O = glasses
				if(!O.up && tinted_weldhelh)
					client.screen += global_hud.darkMask

			if(eye_stat > 20)
				if(eye_stat > 30)	client.screen += global_hud.darkMask
				else				client.screen += global_hud.vimpaired

			if(machine)
				if(!machine.check_eye(src))		reset_view(null)
			else
				if(!client.adminobs)			reset_view(null)
		return 1

	proc/handle_random_events()
		// Puke if toxloss is too high
		if(!stat)
			if (getToxLoss() >= 30 && nutrition > 20)
				lastpuke ++
				if(lastpuke >= 25) // about 25 second delay I guess
					Stun(2)

					for(var/mob/O in viewers(world.view, src))
						O.show_message(text("<b>\red [] throws up!</b>", src), 1)
					playsound(loc, 'sound/effects/splat.ogg', 50, 1)

					var/turf/location = loc
					if (istype(location, /turf/simulated))
						location.add_vomit_floor(src, 1)

					nutrition -= 20
					adjustToxLoss(-3)

					// make it so you can only puke so fast
					lastpuke = 0

		//0.1% chance of playing a scary sound to someone who's in complete darkness
		if(isturf(loc) && rand(1,1000) == 1)
			var/turf/currentTurf = loc
			if(!currentTurf.lighting_lumcount)
				playsound_local(src,pick(scarySounds),50, 1, -1)

	proc/handle_stomach()
		spawn(0)
			for(var/mob/living/M in stomach_contents)
				if(M.loc != src)
					stomach_contents.Remove(M)
					continue
				if(istype(M, /mob/living/carbon) && stat != 2)
					if(M.stat == 2)
						M.death(1)
						stomach_contents.Remove(M)
						del(M)
						continue
					if((last_tick_duration))
						if(!(M.status_flags & GODMODE))
							M.adjustBruteLoss(5)
						nutrition += 10

	proc/handle_changeling()
		if(mind && mind.changeling)
			mind.changeling.regenerate()

#undef HUMAN_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS